package com.x.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

/**
 * @title: DataSourceConfig
 * @Author X
 * @Date: 2021/1/11 20:31
 * @Version 1.0
 */
@Configuration
public class DynamicDataSourceConfig {
    private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceConfig.class);

    private final String prefix = "v2_";

    @Value("${mybatis.mapperLocations}")
    private String mapperLocations;
    @Value("${mybatis.typeAliasesPackage}")
    private String typeAliasesPackage;

    @Bean(name = "defaultDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource defaultDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DruidDataSource defaultTargetDataSource = defaultDataSource();
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put("defaultDataSource", defaultTargetDataSource);
        try (Connection connection = defaultTargetDataSource.getConnection()) {
            try (PreparedStatement ps = connection.prepareStatement("select * from ad_project_config"); ResultSet rs = ps.executeQuery()) {
                DynamicCustomerDataSource dynamicCustomerDataSource = null;
                while(rs.next()) {
                    String dataSourceId = rs.getString("app_key");
                    if (StringUtils.isEmpty(dataSourceId)) continue;
                    String _url = String.format(
                            "jdbc:mysql://%s:%d/%s?characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC",
                            rs.getString("db_host"), rs.getInt("db_port"), prefix + rs.getString("db_name"));
                    String _username = rs.getString("db_username");
                    String _password = rs.getString("db_password");
                    try {
                        dynamicCustomerDataSource = new DynamicCustomerDataSource();
                        DruidDataSource createDefaultDruidDataSource =  dynamicCustomerDataSource.createDefaultDruidDataSource();
                        createDefaultDruidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
                        createDefaultDruidDataSource.setUrl(_url);
                        createDefaultDruidDataSource.setUsername(_username);
                        createDefaultDruidDataSource.setPassword(_password);
                        try (Connection WCCdsconn = createDefaultDruidDataSource.getConnection()) {
                            createDefaultDruidDataSource.init();
                            logger.info("dataSourceId: {}, url: {}, 初始化成功", dataSourceId, _url);
                            targetDataSources.put(dataSourceId, createDefaultDruidDataSource);
                        } catch (Exception e) {
                            logger.info("dataSourceId: {}, url: {}, 初始化失败！！！", dataSourceId, _url);
                        }
                    } catch (Exception e) {
                        continue;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new DynamicRoutingDataSource(targetDataSources);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));
        sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }
}
